package com.maodou.core.ui.theme

import androidx.compose.material3.ColorScheme
import androidx.compose.material3.Typography
import androidx.compose.material3.darkColorScheme
import androidx.compose.material3.lightColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Stable
import androidx.compose.ui.unit.Dp

/**
 * 主题配置系统
 * 提供主题切换和自适应功能
 */

// ==================== 主题类型枚举 ====================

/**
 * 主题类型
 */
enum class ThemeType {
    DEFAULT,    // 默认主题（蓝色）
    GREEN,      // 绿色主题
    PURPLE,     // 紫色主题
    SYSTEM      // 跟随系统
}

/**
 * 深色模式类型
 */
enum class DarkModeType {
    LIGHT,      // 浅色模式
    DARK,       // 深色模式
    SYSTEM      // 跟随系统
}

/**
 * 字体大小类型
 */
enum class FontSizeType {
    COMPACT,    // 紧凑
    DEFAULT,    // 默认
    RELAXED     // 宽松
}

/**
 * 布局密度类型
 */
enum class LayoutDensityType {
    COMPACT,    // 紧凑
    DEFAULT,    // 默认
    COMFORTABLE // 舒适
}

// ==================== 主题配置数据类 ====================

/**
 * 主题配置
 */
@Stable
data class ThemeConfig(
    val themeType: ThemeType = ThemeType.DEFAULT,
    val darkModeType: DarkModeType = DarkModeType.SYSTEM,
    val fontSizeType: FontSizeType = FontSizeType.DEFAULT,
    val layoutDensityType: LayoutDensityType = LayoutDensityType.DEFAULT,
    val dynamicColor: Boolean = true,
    val highContrast: Boolean = false
)

// ==================== 主题数据类 ====================

/**
 * 完整的主题数据
 */
@Stable
data class AppTheme(
    val colorScheme: ColorScheme,
    val typography: Typography,
    val spacing: AppSpacing,
    val shapes: AppShapes,
    val config: ThemeConfig
)

/**
 * 应用间距配置
 */
@Stable
data class AppSpacing(
    val extraSmall: Dp,
    val small: Dp,
    val default: Dp,
    val medium: Dp,
    val large: Dp,
    val extraLarge: Dp,
    val huge: Dp
)

/**
 * 应用形状配置
 */
@Stable
data class AppShapes(
    val small: Dp,
    val default: Dp,
    val medium: Dp,
    val large: Dp,
    val extraLarge: Dp
)

// ==================== 主题工厂 ====================

object ThemeFactory {
    
    /**
     * 创建颜色方案
     */
    fun createColorScheme(
        themeType: ThemeType,
        isDark: Boolean,
        highContrast: Boolean = false
    ): ColorScheme {
        return when (themeType) {
            ThemeType.DEFAULT -> createDefaultColorScheme(isDark, highContrast)
            ThemeType.GREEN -> createGreenColorScheme(isDark, highContrast)
            ThemeType.PURPLE -> createPurpleColorScheme(isDark, highContrast)
            ThemeType.SYSTEM -> createDefaultColorScheme(isDark, highContrast)
        }
    }
    
    /**
     * 创建字体排版
     */
    fun createTypography(fontSizeType: FontSizeType): Typography {
        return when (fontSizeType) {
            FontSizeType.COMPACT -> CompactTypography
            FontSizeType.DEFAULT -> DefaultTypography
            FontSizeType.RELAXED -> RelaxedTypography
        }
    }
    
    /**
     * 创建间距配置
     */
    fun createSpacing(layoutDensityType: LayoutDensityType): AppSpacing {
        return when (layoutDensityType) {
            LayoutDensityType.COMPACT -> AppSpacing(
                extraSmall = Spacing.ExtraSmall,
                small = Spacing.Small,
                default = Spacing.Default,
                medium = Spacing.Medium,
                large = Spacing.Large,
                extraLarge = Spacing.ExtraLarge,
                huge = Spacing.Huge
            )
            LayoutDensityType.DEFAULT -> AppSpacing(
                extraSmall = Spacing.Small,
                small = Spacing.Default,
                default = Spacing.Medium,
                medium = Spacing.Large,
                large = Spacing.ExtraLarge,
                extraLarge = Spacing.Huge,
                huge = Spacing.Maximum
            )
            LayoutDensityType.COMFORTABLE -> AppSpacing(
                extraSmall = Spacing.Default,
                small = Spacing.Medium,
                default = Spacing.Large,
                medium = Spacing.ExtraLarge,
                large = Spacing.Huge,
                extraLarge = Spacing.Maximum,
                huge = Spacing.Maximum
            )
        }
    }
    
    /**
     * 创建形状配置
     */
    fun createShapes(): AppShapes {
        return AppShapes(
            small = CornerRadius.Small,
            default = CornerRadius.Default,
            medium = CornerRadius.Medium,
            large = CornerRadius.Large,
            extraLarge = CornerRadius.ExtraLarge
        )
    }
    
    // ==================== 私有方法 ====================
    
    private fun createDefaultColorScheme(isDark: Boolean, highContrast: Boolean): ColorScheme {
        return if (isDark) {
            darkColorScheme(
                primary = if (highContrast) PrimaryColors.Blue100 else DefaultThemeColors.DarkPrimary,
                onPrimary = DefaultThemeColors.DarkOnPrimary,
                primaryContainer = DefaultThemeColors.DarkPrimaryContainer,
                onPrimaryContainer = DefaultThemeColors.DarkOnPrimaryContainer,
                secondary = DefaultThemeColors.DarkSecondary,
                onSecondary = DefaultThemeColors.DarkOnSecondary,
                secondaryContainer = DefaultThemeColors.DarkSecondaryContainer,
                onSecondaryContainer = DefaultThemeColors.DarkOnSecondaryContainer,
                tertiary = DefaultThemeColors.DarkTertiary,
                onTertiary = DefaultThemeColors.DarkOnTertiary,
                tertiaryContainer = DefaultThemeColors.DarkTertiaryContainer,
                onTertiaryContainer = DefaultThemeColors.DarkOnTertiaryContainer,
                background = if (highContrast) NeutralColors.Gray900 else DefaultThemeColors.DarkBackground,
                onBackground = DefaultThemeColors.DarkOnBackground,
                surface = DefaultThemeColors.DarkSurface,
                onSurface = DefaultThemeColors.DarkOnSurface,
                surfaceVariant = DefaultThemeColors.DarkSurfaceVariant,
                onSurfaceVariant = DefaultThemeColors.DarkOnSurfaceVariant,
                error = DefaultThemeColors.DarkError,
                onError = DefaultThemeColors.DarkOnError,
                errorContainer = DefaultThemeColors.DarkErrorContainer,
                onErrorContainer = DefaultThemeColors.DarkOnErrorContainer,
                outline = DefaultThemeColors.DarkOutline,
                outlineVariant = DefaultThemeColors.DarkOutlineVariant
            )
        } else {
            lightColorScheme(
                primary = if (highContrast) PrimaryColors.Blue700 else DefaultThemeColors.LightPrimary,
                onPrimary = DefaultThemeColors.LightOnPrimary,
                primaryContainer = DefaultThemeColors.LightPrimaryContainer,
                onPrimaryContainer = DefaultThemeColors.LightOnPrimaryContainer,
                secondary = DefaultThemeColors.LightSecondary,
                onSecondary = DefaultThemeColors.LightOnSecondary,
                secondaryContainer = DefaultThemeColors.LightSecondaryContainer,
                onSecondaryContainer = DefaultThemeColors.LightOnSecondaryContainer,
                tertiary = DefaultThemeColors.LightTertiary,
                onTertiary = DefaultThemeColors.LightOnTertiary,
                tertiaryContainer = DefaultThemeColors.LightTertiaryContainer,
                onTertiaryContainer = DefaultThemeColors.LightOnTertiaryContainer,
                background = DefaultThemeColors.LightBackground,
                onBackground = DefaultThemeColors.LightOnBackground,
                surface = DefaultThemeColors.LightSurface,
                onSurface = DefaultThemeColors.LightOnSurface,
                surfaceVariant = DefaultThemeColors.LightSurfaceVariant,
                onSurfaceVariant = DefaultThemeColors.LightOnSurfaceVariant,
                error = DefaultThemeColors.LightError,
                onError = DefaultThemeColors.LightOnError,
                errorContainer = DefaultThemeColors.LightErrorContainer,
                onErrorContainer = DefaultThemeColors.LightOnErrorContainer,
                outline = DefaultThemeColors.LightOutline,
                outlineVariant = DefaultThemeColors.LightOutlineVariant
            )
        }
    }
    
    private fun createGreenColorScheme(isDark: Boolean, highContrast: Boolean): ColorScheme {
        return if (isDark) {
            darkColorScheme(
                primary = if (highContrast) SemanticColors.Success50 else GreenThemeColors.DarkPrimary,
                onPrimary = GreenThemeColors.DarkOnPrimary,
                primaryContainer = GreenThemeColors.DarkPrimaryContainer,
                onPrimaryContainer = GreenThemeColors.DarkOnPrimaryContainer,
                secondary = GreenThemeColors.DarkSecondary,
                onSecondary = GreenThemeColors.DarkOnSecondary,
                secondaryContainer = GreenThemeColors.DarkSecondaryContainer,
                onSecondaryContainer = GreenThemeColors.DarkOnSecondaryContainer,
                tertiary = GreenThemeColors.DarkTertiary,
                onTertiary = GreenThemeColors.DarkOnTertiary,
                tertiaryContainer = GreenThemeColors.DarkTertiaryContainer,
                onTertiaryContainer = GreenThemeColors.DarkOnTertiaryContainer,
                background = if (highContrast) NeutralColors.Gray900 else GreenThemeColors.DarkBackground,
                onBackground = GreenThemeColors.DarkOnBackground,
                surface = GreenThemeColors.DarkSurface,
                onSurface = GreenThemeColors.DarkOnSurface,
                surfaceVariant = GreenThemeColors.DarkSurfaceVariant,
                onSurfaceVariant = GreenThemeColors.DarkOnSurfaceVariant,
                error = GreenThemeColors.DarkError,
                onError = GreenThemeColors.DarkOnError,
                errorContainer = GreenThemeColors.DarkErrorContainer,
                onErrorContainer = GreenThemeColors.DarkOnErrorContainer,
                outline = GreenThemeColors.DarkOutline,
                outlineVariant = GreenThemeColors.DarkOutlineVariant
            )
        } else {
            lightColorScheme(
                primary = if (highContrast) SemanticColors.Success700 else GreenThemeColors.LightPrimary,
                onPrimary = GreenThemeColors.LightOnPrimary,
                primaryContainer = GreenThemeColors.LightPrimaryContainer,
                onPrimaryContainer = GreenThemeColors.LightOnPrimaryContainer,
                secondary = GreenThemeColors.LightSecondary,
                onSecondary = GreenThemeColors.LightOnSecondary,
                secondaryContainer = GreenThemeColors.LightSecondaryContainer,
                onSecondaryContainer = GreenThemeColors.LightOnSecondaryContainer,
                tertiary = GreenThemeColors.LightTertiary,
                onTertiary = GreenThemeColors.LightOnTertiary,
                tertiaryContainer = GreenThemeColors.LightTertiaryContainer,
                onTertiaryContainer = GreenThemeColors.LightOnTertiaryContainer,
                background = GreenThemeColors.LightBackground,
                onBackground = GreenThemeColors.LightOnBackground,
                surface = GreenThemeColors.LightSurface,
                onSurface = GreenThemeColors.LightOnSurface,
                surfaceVariant = GreenThemeColors.LightSurfaceVariant,
                onSurfaceVariant = GreenThemeColors.LightOnSurfaceVariant,
                error = GreenThemeColors.LightError,
                onError = GreenThemeColors.LightOnError,
                errorContainer = GreenThemeColors.LightErrorContainer,
                onErrorContainer = GreenThemeColors.LightOnErrorContainer,
                outline = GreenThemeColors.LightOutline,
                outlineVariant = GreenThemeColors.LightOutlineVariant
            )
        }
    }
    
    private fun createPurpleColorScheme(isDark: Boolean, highContrast: Boolean): ColorScheme {
        return if (isDark) {
            darkColorScheme(
                primary = if (highContrast) PurpleThemeColors.DarkOnPrimary else PurpleThemeColors.DarkPrimary,
                onPrimary = PurpleThemeColors.DarkOnPrimary,
                primaryContainer = PurpleThemeColors.DarkPrimaryContainer,
                onPrimaryContainer = PurpleThemeColors.DarkOnPrimaryContainer,
                secondary = PurpleThemeColors.DarkSecondary,
                onSecondary = PurpleThemeColors.DarkOnSecondary,
                secondaryContainer = PurpleThemeColors.DarkSecondaryContainer,
                onSecondaryContainer = PurpleThemeColors.DarkOnSecondaryContainer,
                tertiary = PurpleThemeColors.DarkTertiary,
                onTertiary = PurpleThemeColors.DarkOnTertiary,
                tertiaryContainer = PurpleThemeColors.DarkTertiaryContainer,
                onTertiaryContainer = PurpleThemeColors.DarkOnTertiaryContainer,
                background = if (highContrast) NeutralColors.Gray900 else PurpleThemeColors.DarkBackground,
                onBackground = PurpleThemeColors.DarkOnBackground,
                surface = PurpleThemeColors.DarkSurface,
                onSurface = PurpleThemeColors.DarkOnSurface,
                surfaceVariant = PurpleThemeColors.DarkSurfaceVariant,
                onSurfaceVariant = PurpleThemeColors.DarkOnSurfaceVariant,
                error = PurpleThemeColors.DarkError,
                onError = PurpleThemeColors.DarkOnError,
                errorContainer = PurpleThemeColors.DarkErrorContainer,
                onErrorContainer = PurpleThemeColors.DarkOnErrorContainer,
                outline = PurpleThemeColors.DarkOutline,
                outlineVariant = PurpleThemeColors.DarkOutlineVariant
            )
        } else {
            lightColorScheme(
                primary = if (highContrast) PurpleThemeColors.LightOnPrimaryContainer else PurpleThemeColors.LightPrimary,
                onPrimary = PurpleThemeColors.LightOnPrimary,
                primaryContainer = PurpleThemeColors.LightPrimaryContainer,
                onPrimaryContainer = PurpleThemeColors.LightOnPrimaryContainer,
                secondary = PurpleThemeColors.LightSecondary,
                onSecondary = PurpleThemeColors.LightOnSecondary,
                secondaryContainer = PurpleThemeColors.LightSecondaryContainer,
                onSecondaryContainer = PurpleThemeColors.LightOnSecondaryContainer,
                tertiary = PurpleThemeColors.LightTertiary,
                onTertiary = PurpleThemeColors.LightOnTertiary,
                tertiaryContainer = PurpleThemeColors.LightTertiaryContainer,
                onTertiaryContainer = PurpleThemeColors.LightOnTertiaryContainer,
                background = PurpleThemeColors.LightBackground,
                onBackground = PurpleThemeColors.LightOnBackground,
                surface = PurpleThemeColors.LightSurface,
                onSurface = PurpleThemeColors.LightOnSurface,
                surfaceVariant = PurpleThemeColors.LightSurfaceVariant,
                onSurfaceVariant = PurpleThemeColors.LightOnSurfaceVariant,
                error = PurpleThemeColors.LightError,
                onError = PurpleThemeColors.LightOnError,
                errorContainer = PurpleThemeColors.LightErrorContainer,
                onErrorContainer = PurpleThemeColors.LightOnErrorContainer,
                outline = PurpleThemeColors.LightOutline,
                outlineVariant = PurpleThemeColors.LightOutlineVariant
            )
        }
    }
}